import ViewUIPlus from "view-ui-plus";
import areaCodes from "@/utils/areaCodes";
import surname from "@/data/surname";
import ReRegExp from 'reregexp';

class SimpleUtils {
    root;

    toRedirectUrl(url) {
        return "#/redirect?target=" + encodeURIComponent(url);
    }

    copy(text) {
        navigator.clipboard.writeText(text).then(() => {
            ViewUIPlus.Message.success('复制成功')
        }).catch(err => {
            ViewUIPlus.Message.error('复制失败');
        });
    }

    /**
     * 数字大小写字母集
     */
    static get BASE_CHARACTER() {
        return "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
    }

    /**
     * 区域编码列表
     */
    static get AREA_LIST() {
        return areaCodes;
    }

    /**
     * 生成UUID
     */
    uuid(simple) {
        let d = new Date().getTime();
        let template = "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx";
        if (simple) {
            template = "xxxxxxxxxxxx4xxxyxxxxxxxxxxxxxxx";
        }
        return template.replace(/[xy]/g, function (c) {
            let r = (d + Math.random() * 16) % 16 | 0;
            d = Math.floor(d / 16);
            return (c === 'x' ? r : (r & 0x3 | 0x8)).toString(16);
        });
    }

    /**
     * 生成随机手机号
     */
    randomPhoneNumber() {
        let number = this.randomNumber(130, 199) + '';
        for (let i = 0; i < 8; i++) { // 生成后续10位数字
            number += Math.floor(Math.random() * 10); // 生成0-9之间的随机整数
        }
        return number;
    }

    /**
     * 取字符串中随机一个字符
     * @series 字符串
     * @len 长度
     */
    dicingChar(series, len) {
        if (!len) {
            return series[~~(Math.random() * series.length)]
        }
        let res = "";
        for (let i = 0; i < len; i++) {
            res += series[~~(Math.random() * series.length)]
        }
        return res;
    }

    /**
     * 车牌号区域集合
     */
    static get PLATE_AREA_LIST() {
        return '京津冀晋辽吉沪苏浙皖闽琼赣鲁豫鄂湘粤渝川贵云陕甘蒙黑桂藏青宁新'.split('');
    }

    /**
     * 生成随机车牌号
     */
    randomPlate(area) {
        let total = 5;
        let stateList = area || SimpleUtils.PLATE_AREA_LIST;
        let charList = 'ABCDEFGHJKLMNQPRSTUVWXYZ'
        let numList = '1234567890'
        let halfList = [charList, numList]
        let state = this.dicingChar(stateList)
        let city = this.dicingChar(charList)
        let sequence = ''
        while (total--) {
            sequence += this.dicingChar(halfList[Math.round(Math.random())])
        }
        return `${state}${city}${sequence}`;
    }

    /**
     * 生成随机数字字母串
     */
    randomAlphanumeric(len = 32) {
        const characters = SimpleUtils.BASE_CHARACTER;
        let result = '';
        for (let i = 0; i < len; i++) {
            const randomIndex = Math.floor(Math.random() * characters.length);
            result += characters.charAt(randomIndex);
        }
        return result;
    }

    /**
     * 两个数间的随机数
     */
    randomNumber(minNum, maxNum, float) {
        const random = Math.random() * (maxNum - minNum + 1);
        if (float) {
            return random + minNum;
        }
        return Math.floor(random) + minNum;
    }

    /**
     * 随机生成姓名，object类型
     * @returns {{surname: {pinyin: string, name: string}, givenName: string}}
     */
    randomFullNameObject() {
        const givenNames = [
            "子璇", "淼", "国栋", "夫子", "瑞堂", "甜", "敏", "尚", "国贤", "贺祥", "晨涛",
            "昊轩", "易轩", "益辰", "益帆", "益冉", "瑾春", "瑾昆", "春齐", "杨", "文昊",
            "东东", "雄霖", "浩晨", "熙涵", "溶溶", "冰枫", "欣欣", "宜豪", "欣慧", "建政",
            "美欣", "淑慧", "文轩", "文杰", "欣源", "忠林", "榕润", "欣汝", "慧嘉", "新建",
            "建林", "亦菲", "林", "冰洁", "佳欣", "涵涵", "禹辰", "淳美", "泽惠", "伟洋",
            "涵越", "润丽", "翔", "淑华", "晶莹", "凌晶", "苒溪", "雨涵", "嘉怡", "佳毅",
            "子辰", "佳琪", "紫轩", "瑞辰", "昕蕊", "萌", "明远", "欣宜", "泽远", "欣怡",
            "佳怡", "佳惠", "晨茜", "晨璐", "运昊", "汝鑫", "淑君", "晶滢", "润莎", "榕汕",
            "佳钰", "佳玉", "晓庆", "一鸣", "语晨", "添池", "添昊", "雨泽", "雅晗", "雅涵",
            "清妍", "诗悦", "嘉乐", "晨涵", "天赫", "玥傲", "佳昊", "天昊", "萌萌", "若萌",
            '歆瑶', '玉通', '语蝶', '佩儒', '莞茉', '意超', '兰溪', '百成', '理菡', '云新',
            '宇琼', '朝健', '萱妍', '元生', '雨霏', '成锦', '语汐', '东锋', '若颖', '明轩',
            '冰欣', '秋胜', '梓萌', '玉润', '君怡', '勇智', '泓仪', '欣德', '意涵', '宇信',
            '语汐', '知之', '若颖', '景铄', '梦柔', '泓涵', '舒苒', '学思', '巧沁', '侃如',
            '露辰', '梵天', '芳妍', '徐萱', '娇语', '锦帆', '萌琪', '楚天', '紫菱', '远帆',
            '意然', '任贤', '清溪', '德泽', '予心', '忆泽', '泷静', '思泉', '蔓芩', '玮川',
            '恬简', '钊洋', '苁依', '若一', '依斐', '浩全', '韶影', '瑞振', '文茵', '思衡',
            '子衿', '苏华', '语汐', '文显', '舒苒', '崇新', '若秋', '路平', '可昕', '向辉',
            '夕瑶', '益林', '诗柳', '意然', '一韬', '玥珊', '生俊', '昕悦', '乐宜', '希月',
            '天赫', '歆瑶', '元威', '诗琪', '继扬', '依嘉', '翰东', '春惠', '润山', '紫绮'
        ]

        const i = this.randomNumber(0, surname.length - 1);
        const familyName = surname[i];

        const j = this.randomNumber(0, givenNames.length - 1);
        const givenName = givenNames[j];

        return {
            surname: familyName,
            givenName: givenName
        };
    }

    /**
     * 随机姓名
     */
    randomFullName() {
        const randomName = this.randomFullNameObject();
        return randomName.surname.name + randomName.givenName;
    }

    toDate2(str) {

    }

    toDate(str) {
        if (str instanceof Date) {
            return str;
        }
        str = str.replace(/-/g, "/");
        str = str.replace("年", "/");
        str = str.replace("月", "/");
        str = str.replace("日", "");

        const allNum = /^\d+$/.test(str);
        const len = str.length;

        if (allNum) {
            if (len === 10 || len === 13) {
                if (len === 10) {
                    // 10位的需乘1000
                    str = (parseInt(str) * 1000).toString();
                }
                // 时间戳直接转日期
                return new Date(parseInt(str));
            } else if (len === 14) {
                // 20240212145318，年月日时分秒格式
                let year = str.substr(0, 4);
                let month = str.substr(4, 2);
                let day = str.substr(6, 2);
                let h = str.substr(8, 2);
                let m = str.substr(10, 2);
                let s = str.substr(12, 2);
                return new Date(year + "/" + month + "/" + day + " " + h + ":" + m + ":" + s);
            } else if (len === 12) {
                // 202413123022，年月日省略0
                let year = str.substr(0, 4);
                let month = str.substr(4, 1);
                let day = str.substr(5, 1);
                let h = str.substr(6, 2);
                let m = str.substr(8, 2);
                let s = str.substr(10, 2);
                return new Date(year + "/" + month + "/" + day + " " + h + ":" + m + ":" + s);
            } else if (len === 9) {
                // 202451236，年月日时分秒省略0
                let year = str.substr(0, 4);
                let month = str.substr(4, 1);
                let day = str.substr(5, 1);
                let h = str.substr(6, 1);
                let m = str.substr(7, 1);
                let s = str.substr(8, 1);
                return new Date(year + "/" + month + "/" + day + " " + h + ":" + m + ":" + s);
            } else if (len === 8) {
                // 20241220，年月日
                let year = str.substr(0, 4);
                let month = str.substr(4, 2);
                let day = str.substr(6, 2);
                return new Date(year + "/" + month + "/" + day);
            } else if (len === 6) {
                // 202463，年月日，省0
                let year = str.substr(0, 4);
                let month = str.substr(4, 1);
                let day = str.substr(5, 1);
                return new Date(year + "/" + month + "/" + day);
            }
            return new Date(parseInt(str));
        } else {
            if (len === 14) {
                // 2024/3/1091833
                let ymd = str.substr(0, 8);
                let h = str.substr(8, 2);
                let m = str.substr(10, 2);
                let s = str.substr(12, 2);
                return new Date(ymd + " " + h + ":" + m + ":" + s);
            } else if (len === 15) {
                // 2024/2/2 123420
                let ymd = str.substr(0, 8);
                let h = str.substr(9, 2);
                let m = str.substr(11, 2);
                let s = str.substr(13, 2);
                return new Date(ymd + " " + h + ":" + m + ":" + s);
            } else if (len === 16) {
                // 2024/2/211:23:30
                let ymd = str.substr(0, 8);
                let hms = str.substr(8, 8);
                return new Date(ymd + " " + hms);
            } else if (len === 18) {
                // 2024/01/2313:20:36
                let ymd = str.substr(0, 10);
                let hms = str.substr(10, 8);
                return new Date(ymd + " " + hms);
            } else if (len === 12) {
                // 2024/1/11133
                let ymd = str.substr(0, 8);
                let h = str.substr(8, 2);
                let m = str.substr(10, 2);
                let s = "00";
                return new Date(ymd + " " + h + ":" + m + ":" + s);
            }
        }
        return new Date(str);
    }

    /**
     * 格式化日期
     * @param date 日期
     * @param fmt 格式
     */
    formatDateTime(date, fmt) {
        const o = {
            "M+": date.getMonth() + 1,     //月份
            "d+": date.getDate(),     //日
            "H+": date.getHours(),     //小时
            "m+": date.getMinutes(),     //分
            "s+": date.getSeconds(),     //秒
            "q+": Math.floor((date.getMonth() + 3) / 3), //季度
            "S": date.getMilliseconds()    //毫秒
        };
        if (/(y+)/.test(fmt))
            fmt = fmt.replace(RegExp.$1, (date.getFullYear() + "").substr(4 - RegExp.$1.length));
        for (let k in o)
            if (new RegExp("(" + k + ")").test(fmt))
                fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (("00" + o[k]).substr(("" + o[k]).length)));
        return fmt;
    }

    /**
     * 随机日期（默认1970-01-01到现在）
     * @start 开始日期
     * @end 结束日期
     */
    randomDate(start, end) {
        if (!start) {
            start = new Date('1970-01-01');
        } else {
            start = new Date(start);
        }
        if (!end) {
            end = new Date();
        } else {
            end = new Date(end);
        }

        // 计算两个日期之间相差的毫秒数
        const timeDiff = Math.abs(end.getTime() - start.getTime());
        // 生成随机的毫秒数
        const randomTime = this.randomNumber(0, timeDiff);
        // 根据随机毫秒数计算得到随机日期
        return new Date(start.getTime() + randomTime);
    }

    /**
     * 随机身份证号
     */
    randomIDCard(areaCode) {
        const coefficientArray = ["7", "9", "10", "5", "8", "4", "2", "1", "6", "3", "7", "9", "10", "5", "8", "4", "2"];// 加权因子
        const lastNumberArray = ["1", "0", "X", "9", "8", "7", "6", "5", "4", "3", "2"];// 校验码
        const address = areaCode || areaCodes[this.randomNumber(0, areaCodes.length - 1)].code; // 住址
        const randomDate = this.randomDate();
        const birthday = this.formatDateTime(randomDate, 'yyyyMMdd'); // 生日
        const s = Math.floor(Math.random() * 10).toString() + Math.floor(Math.random() * 10).toString() + Math.floor(Math.random() * 10).toString();
        const array = (address + birthday + s).split("");
        let total = 0;
        for (let i in array) {
            total = total + parseInt(array[i]) * parseInt(coefficientArray[i]);
        }
        const lastNumber = lastNumberArray[parseInt(total % 11)];
        return address + birthday + s + lastNumber;

    }

    /**
     * 银行卡信息Map
     */
    static get BANK_INFO_MAP() {
        const mapRes = {};
        for (const item of this.BANK_INFO_LIST) {
            mapRes[item.code] = mapRes;
        }
        return mapRes;
    }

    // code：1位数字，0-9，标识银行类别。0-中央银行；1-国有独资商业银行；2-政策性银行；3-其商业银行；4-非银行金融机构；5、6、7-外资银行；9-特许参与者；8-待分配。
    /**
     * 银行卡信息数字
     */
    static get BANK_INFO_LIST() {
        return [{
            code: "102",
            name: "中国工商银行",
            prefix: ["6222", "9558"],
            font_class: "gongshangyinhang"
        }, {
            code: "103",
            name: "中国农业银行",
            prefix: ["6228", "9559"],
            font_class: "nonghang"
        }, {
            code: "104",
            name: "中国银行",
            prefix: ["6216", "4563", "6013"],
            font_class: "zhongguoyinhang"
        }, {
            code: "105",
            name: "中国建设银行",
            prefix: ["6627", "4367"],
            font_class: "jiansheyinhang"
        }, {
            code: "201",
            name: "国家开发银行",
            prefix: ["1311"],
            font_class: "guojiakaifayinhang"
        }, {
            code: "203",
            name: "中国农业发展银行",
            prefix: ["8948"],
            font_class: "zhongguonongyefazhanyinhang"
        }, {
            code: "301",
            name: "交通银行",
            prefix: ["6014", "5218"],
            font_class: "jiaotongyinhang"
        }, {
            code: "302",
            name: "中信实业银行",
            font_class: "zhongxinshiyeyinhang"
        }, {
            code: "303",
            name: "中国光大银行",
            prefix: ["6282", "3568"],
            font_class: "guangdayinhang"
        }, {
            code: "304",
            name: "华夏银行",
            font_class: "huaxiayinhang"
        }, {
            code: "305",
            name: "中国民生银行",
            prefix: ["6226", "4218"],
            font_class: "zhongguominshengyinhang"
        }, {
            code: "306",
            name: "广东发展银行",
            prefix: ["6225", "9111"],
            font_class: "guangfayinhang"
        }, {
            code: "307",
            name: "深圳发展银行",
            font_class: "shenzhenfazhanyinhang"
        }, {
            code: "308",
            name: "招商银行",
            font_class: "zhaoshangyinhang"
        }, {
            code: "309",
            name: "兴业银行",
            prefix: ["6229", "4864"],
            font_class: "xingyeyinhang"
        }, {
            code: "310",
            name: "上海浦东发展银行",
            font_class: "pufayinhang"
        }, {
            code: "313",
            name: "城市商业银行",
            font_class: "chengshishangyeyinhang"
        }, {
            code: "314",
            name: "农村商业银行",
            font_class: "nongcunshangyeyinhang"
        }, {
            code: "401",
            name: "城市信用社",
            font_class: "chengshixinyongsheyinhang"
        }, {
            code: "402",
            name: "农村信用社",
            prefix: ["6210"],
            font_class: "nongcunxinyongshe"
        }, {
            code: "403",
            name: "中国邮政储蓄银行",
            prefix: ["6221", "6210"],
            font_class: "zhongguoyouzhengchuxuyinhang"
        }]
    }

    getHasPrefixBankList() {
        return SimpleUtils.BANK_INFO_LIST.filter(item => item.prefix != null && item.prefix.length > 0);
    }

    /**
     * 随机银行卡号
     */
    randomBankNumber(bankCode) {
        const banks = this.getHasPrefixBankList();
        let bank = banks[this.randomNumber(0, banks.length - 1)];
        if (bankCode) {
            bank = banks.find(item => item.code === bankCode);
        }
        let prefix = bank.prefix[0];
        prefix += this.randomNumber(10, 99);

        for (let j = 0; j < 13; j++) {
            prefix = prefix + Math.floor(Math.random() * 10);
        }
        return prefix;
    }

    /**
     * 判断是否移动端
     */
    isMobile() {
        const userAgentInfo = navigator.userAgent;
        return /Android|webOS|iPhone|iPad|iPod|BlackBerry/i.test(userAgentInfo);
    }

    /**
     * 随机颜色
     */
    randomColor() {
        return '#' + Math.floor(Math.random() * 16777215).toString(16);
    }

    generateStringFromRegex(reg) {
        return new ReRegExp(reg).build();
    }
}

const simpleUtils = new SimpleUtils();

simpleUtils.root = SimpleUtils;

export default simpleUtils;
